package com.syh.jn.scm.domain.supplier.entity.finance;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.core.ddd.domain.CodeExpEnum;
import com.syh.core.ddd.domain.CodeGenerateUtil;
import com.syh.jn.scm.domain.supplier.repository.finance.StatementAccountBillReadRepository;
import com.syh.jn.scm.dto.supplier.finance.ReceiptBillMto;
import com.syh.jn.scm.dto.supplier.finance.ReceiptBillSto;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.service.api.supplier.finance.enums.ReceiptBillEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;

/**
 * 收款单
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ReceiptBill extends AbstractSimpleAggregate<Long> {
  public ReceiptBill() {
  }

  /**
   * 构造函数增加收款单
   *
   * @param sto
   */
  public ReceiptBill(ReceiptBillSto sto) {
    ExtAssert.notNull(sto, "对象为空");
    ValidationUtils.validate(sto);
    if (Short.valueOf("0").equals(sto.getCustomerType())) {
      throw new BusinessException("上游不允许收款");
    }
    //  系统默认生成的字段
    ExtBeanUtils.copyProperties(sto, this, false);
    this.lockStatus = ReceiptBillEnum.UNLOCK.getStatus();
    this.receiptState = ReceiptBillEnum.OUR_STAYCONFIRM.getStatus();
    this.confirmState = ReceiptBillEnum.OTHERPARTY_STAYCONFIRM.getStatus();
    this.createTimeStamp = System.currentTimeMillis();
    this.code = CodeGenerateUtil.codeGenerate(CodeExpEnum.RECEIIPT_BILL_EXP.getCodeExp(), sto.getCustomerId());

    this.checkMoney();
  }

  /**
   * 修改收款单
   *
   * @param mto
   */
  public void modify(ReceiptBillMto mto) {
    ExtAssert.notNull(mto, "对象为空");
    ValidationUtils.validate(mto);
    if (ReceiptBillEnum.OUR_CONFIRM.getStatus().equals(this.receiptState)) {
      throw new BusinessException("财务已确认到账,修改失败!");
    }
    ExtBeanUtils.copyProperties(mto, this);
    this.checkMoney();
    this.lastUpdateTimeStamp = System.currentTimeMillis();
  }

  /**
   * 数据销毁
   */
  public void destroy() {
    if (ReceiptBillEnum.OUR_CONFIRM.getStatus().equals(this.receiptState)
            || ReceiptBillEnum.OTHERPARTY_CONFIRM.getStatus().equals(this.confirmState)) {
      throw new BusinessException("财务已确认到账,删除失败!");
    }
  }

  /**
   * 确认到账
   */
  public void confirm() {
    this.checkMoney();
    this.receiptState = ReceiptBillEnum.OUR_CONFIRM.getStatus();
    if (this.confirmState.equals(ReceiptBillEnum.OTHERPARTY_CONFIRM.getStatus()))
      this.lockStatus = ReceiptBillEnum.LOCK.getStatus();
  }

  /**
   * 取消到账
   */
  public void cancel() {
    if (this.lockStatus.equals(ReceiptBillEnum.LOCK.getStatus())) {
      throw new BusinessException("收款单为锁定状态,不可以取消");
    }
    this.receiptState = ReceiptBillEnum.OUR_STAYCONFIRM.getStatus();
  }

  /**
   * 解锁
   */
  public void unLock() {
    if (!this.confirmState.equals(ReceiptBillEnum.OTHERPARTY_CONFIRM.getStatus()) || !this.receiptState.equals(ReceiptBillEnum.OUR_CONFIRM.getStatus())) {
      throw new BusinessException("双方没确认,不可以解锁");
    }
    this.lockStatus = ReceiptBillEnum.UNLOCK.getStatus();
  }

  /**
   * 检查对账单金额
   */
  public void checkMoney() {
    if (this.price.compareTo(BigDecimal.ZERO) <= 0) {
      throw new BusinessException("收款金额不正确，请检查！");
    }
    StatementAccountBillReadRepository statementBillRead = (StatementAccountBillReadRepository) SpringContextUtils.getBean(StatementAccountBillReadRepository.class);
    StatementAccountBill statement = statementBillRead.getById(this.statementOfAccountId);
    if (this.id == null ) {
      BigDecimal notGeneratedPaymentAmt = statement.getPrice().subtract(statement.getGeneratedCollectionsPrice());
      if (this.price.compareTo(notGeneratedPaymentAmt) > 0) {
        throw new BusinessException("当前对账单未生成支付金额为：" + notGeneratedPaymentAmt + "元。收款金额不能大于未生成金额！");
      }
    }
    BigDecimal notPaymentAmt = statement.getPrice().subtract(statement.getMakeCollectionsPrice());
    if (this.price.compareTo(notPaymentAmt) > 0) {
      throw new BusinessException("当前对账单未支付金额为：" + notPaymentAmt + "元。付款金额不能大于未付金额！");
    }
  }

  /**
   * 收款单编号
   */
  private String code;
  /**
   * 对账单id
   */
  private Long statementOfAccountId;
  /**
   * 客户类型: 0上游, 1下游, 2物流
   */
  private Short customerType;
  /**
   * 锁定状态(0 未锁定 1 已锁定 )双方确认后自动锁定，锁定后为最终状态，将不可再修改
   */
  private Short lockStatus;
  /**
   * 收款单状态:-1未到账, 1已到账
   */
  private Short receiptState;
  /**
   * 录单人id
   */
  private Long brokerageId;
  /**
   * 客户id
   */
  private Long customerId;
  /**
   * 我方开户行
   */
  private String ourAccountBank;
  /**
   * 我方开户支行
   */
  private String ourAccountBranchBank;
  /**
   * 我方银行账号
   */
  private String ourAccountBankCode;
  /**
   * 我方地址省 市 区
   */
  private String ourArea;
  /**
   * 我方支行地址
   */
  private String ourBranchBankAddress;
  /**
   * 对方开户行
   */
  private String otherPartyAccountBank;
  /**
   * 对方开户支行
   */
  private String otherPartyAccountBranchBank;
  /**
   * 对方银行账号
   */
  private String otherPartyAccountBankCode;
  /**
   * 对方地址省 市 区
   */
  private String otherPartyArea;
  /**
   * 对方支行地址
   */
  private String otherPartyBranchBankAddress;
  /**
   * 收款金额
   */
  private BigDecimal price;
  /**
   * 收款日期
   */
  private Long inputTimestamp;
  /**
   * 银行流水号
   */
  private String bankStatement;
  /**
   * 备注
   */
  private String remark;
  /**
   * 对方确认是否付款：-1未付款, 1已付款
   */
  private Short confirmState;
  /**
   * 归属端id
   */
  private Long businessEntityId;
}
